// TestConsoleSuite.cpp : Defines the entry point for the console application.
//

#include "TestConsoleBase.h"
#include "DSInterfaceWrapper.h"

LogHelper logHelper;
void launchTest(TestRunner* a_pTestRunner);

//TEST : STACK
bool testIntStack(NativeIntStack* a_oIntStack);
bool testIntArrayStack();
bool testIntConcurrentArrayStack();
bool testIntLinkedStack();
bool testIntConcurrentLinkedStack();

//TEST : QUEUE
bool testIntQueue(NativeIntQueue* a_oIntArrayQueue);
bool testIntArrayQueue();
bool testIntConcurrentArrayQueue();
bool testIntLinkedQueue();
bool testIntConcurrentLinkedQueue();

int _tmain(int argc, _TCHAR* argv[])
{
	TestRunner testRunner;
	testRunner.addTest(_T("IntegerArrayStack"), testIntArrayStack);
	testRunner.addTest(_T("IntegerConcurrentArrayStack"), testIntConcurrentArrayStack);
	testRunner.addTest(_T("IntegerLinkedStack"), testIntLinkedStack);
	testRunner.addTest(_T("IntegerConcurrentLinkedStack"), testIntConcurrentLinkedStack);
	testRunner.addTest(_T("IntegerArrayQueue"), testIntArrayQueue);
	testRunner.addTest(_T("IntegerConcurrentArrayQueue"), testIntConcurrentArrayQueue);
	testRunner.addTest(_T("IntegerLinkedQueue"), testIntLinkedQueue);
	testRunner.addTest(_T("IntegerConcurrentLinkedQueue"), testIntConcurrentLinkedQueue);

	launchTest(&testRunner);

	return 0;
}

void launchTest(TestRunner* a_pTestRunner) {

	logHelper.writeLog(_T("TESTING ON CONSOLE MODE IS STARTED"));

	a_pTestRunner->executeTest();

	int totalCount = a_pTestRunner->getTotalCount();
	int succeedCount = a_pTestRunner->getSucceedCount();
	int failedCount = a_pTestRunner->getFailedCount();
	logHelper.writeLog(_T("TESTING ON CONSOLE MODE IS FINISHED : Total : %d (Succeed : %d Failed : %d)"), totalCount, succeedCount, failedCount);
	if(failedCount != 0) {
		const _TCHAR** failedModuleNames = new const _TCHAR*[failedCount];
		a_pTestRunner->getFailedModuleNames(failedModuleNames, failedCount);

		logHelper.writeLog(_T("FAILED MODULES : "));
		for(int i = 0; i < failedCount; i++) {
			logHelper.writeLog(_T("\t: %s"), failedModuleNames[i]);
		}
	}
}

bool testIntArrayStack() {
	
	logHelper.writeLog(_T("START : testIntArrayStack"));
	NativeIntArrayStack intArrayStack(5, false);
	bool ret = testIntStack(&intArrayStack);
	logHelper.writeLog(_T("END : testIntArrayStack"));
	return ret;
}

bool testIntConcurrentArrayStack() {

	logHelper.writeLog(_T("START : testIntConcurrentArrayStack"));
	NativeIntArrayStack intConcurrentArrayStack(5, true);
	bool ret = testIntStack(&intConcurrentArrayStack);
	logHelper.writeLog(_T("END : testIntConcurrentArrayStack"));
	return ret;
}

bool testIntLinkedStack() {

	logHelper.writeLog(_T("START : testIntLinkedStack"));
	NativeIntLinkedStack intLinkedStack(5, false);
	bool ret = testIntStack(&intLinkedStack);
	logHelper.writeLog(_T("END : testIntLinkedStack"));
	return ret;
}

bool testIntConcurrentLinkedStack() {

	logHelper.writeLog(_T("START : testIntConcurrentLinkedStack"));
	NativeIntLinkedStack intConcurrentLinkedStack(5, true);
	bool ret = testIntStack(&intConcurrentLinkedStack);
	logHelper.writeLog(_T("END : testIntConcurrentLinkedStack"));
	return ret;
}

bool testIntStack(NativeIntStack* a_oIntStack) {

	try {
		for(int data = 1; data < 11; data++) {
			if(a_oIntStack->canPush()) {
				a_oIntStack->push(data);
				logHelper.writeLog(_T("pushed : value : %d"), data);
			}
			else {
				logHelper.writeLog(_T("pushed failed"));
			}
		}

		for(int index = 0; index < 10; index++) {
			if(a_oIntStack->canPop()) {
				int value = a_oIntStack->pop();
				logHelper.writeLog(_T("popped : value : %d"), value);
			}
			else {
				logHelper.writeLog(_T("pop failed : "));
			}
		}
	}
	catch (DSException& a_exception) {
		logHelper.writeLog(_T("Exception occured %s"), a_exception.what());
		return false;
	}

	return true;
}

bool testIntArrayQueue() {
	logHelper.writeLog(_T("START : testIntArrayQueue"));
	NativeIntArrayQueue intArrayQueue(5, false);
	bool ret = testIntQueue(&intArrayQueue);
	logHelper.writeLog(_T("END : testIntArrayQueue"));
	return ret;
}
bool testIntConcurrentArrayQueue() {
	logHelper.writeLog(_T("START : testIntConcurrentArrayQueue"));
	NativeIntArrayQueue intArrayQueue(5, true);
	bool ret = testIntQueue(&intArrayQueue);
	logHelper.writeLog(_T("END : testIntConcurrentArrayQueue"));
	return ret;
}
bool testIntLinkedQueue() {
	logHelper.writeLog(_T("START : testIntLinkedQueue"));
	NativeIntLinkedQueue intLinkedQueue(5, false);
	bool ret = testIntQueue(&intLinkedQueue);
	logHelper.writeLog(_T("END : testIntLinkedQueue"));
	return ret;
}
bool testIntConcurrentLinkedQueue() {
	logHelper.writeLog(_T("START : testIntConcurrentLinkedQueue"));
	NativeIntLinkedQueue intLinkedQueue(5, true);
	bool ret = testIntQueue(&intLinkedQueue);
	logHelper.writeLog(_T("END : testIntConcurrentLinkedQueue"));
	return ret;
}

bool testIntQueue(NativeIntQueue* a_oIntQueue) {

	try {
		for(int data = 1; data < 11; data++) {
			if(a_oIntQueue->canOffer()) {
				a_oIntQueue->offer(data);
				logHelper.writeLog(_T("offered : value : %d"), data);
			}
			else {
				logHelper.writeLog(_T("offering failed"));
			}
		}

		for(int index = 0; index < 10; index++) {
			if(a_oIntQueue->canPoll()) {
				int peekedValue = a_oIntQueue->peek();
				int polledValue = a_oIntQueue->poll();
				logHelper.writeLog(_T("peeked value : %d polled value : %d"), peekedValue, polledValue);
			}
			else {
				logHelper.writeLog(_T("polling failed : "));
			}
		}
	}
	catch (DSException& a_exception) {
		logHelper.writeLog(_T("Exception occured %s"), a_exception.what());
		return false;
	}

	return true;
}

